Change to new restart model.
40c9c469LNxLVizOUpOjEaTKKCm8Aw tools/python/xen/xend/sxp.py
40d05079aFRp6NQdo5wIh5Ly31c0cg tools/python/xen/xm/__init__.py
40cf2937gKQcATgXKGtNeWb1PDH5nA tools/python/xen/xm/create.py
+40f552eariuUSB9TWqCPnDLz5zvxMw tools/python/xen/xm/destroy.py
40e41cd2w0I4En6qrJn4em8HkK_oxQ tools/python/xen/xm/help.py
40cf2937isyS250zyd0Q2GuEDoNXfQ tools/python/xen/xm/main.py
40cf2937PSslwBliN1g7ofDy2H_RhA tools/python/xen/xm/opts.py
extra = "4 VMID=%d usr=/dev/sda6" % vmid
#----------------------------------------------------------------------------
-# Set according to whether you want the domain restarted when it exits.
-# The default is False.
-#autorestart = True
+# Set according to whether you want the domain restarted when it exits.
+# The default is 'onreboot', which restarts the domain when it shuts down
+# with exit code reboot.
+# Other values are 'always', and 'never'.
+
+#restart = 'onreboot'
#============================================================================
#----------------------------------------------------------------------------
-# Set according to whether you want the domain restarted when it exits.
-# The default is False.
-#autorestart = True
-
+# Set according to whether you want the domain restarted when it exits.
+# The default is 'onreboot', which restarts the domain when it shuts down
+# with exit code reboot.
+# Other values are 'always', and 'never'.
+#
+#restart = 'onreboot'
#============================================================================
{'op' : 'shutdown',
'reason' : reason })
- def xend_domain_destroy(self, id):
+ def xend_domain_destroy(self, id, reason):
return xend_call(self.domainurl(id),
- {'op' : 'destroy' })
+ {'op' : 'destroy',
+ 'reason' : reason })
def xend_domain_save(self, id, filename):
return xend_call(self.domainurl(id),
def domain_shutdown(self, id, reason='poweroff'):
"""Shutdown domain (nicely).
- - poweroff: domain will restart if has autorestart set.
- - reboot: domain will restart.
- - halt: domain will not restart (even if has autorestart set).
+ - poweroff: restart according to exit code and restart mode
+ - reboot: restart on exit
+ - halt: do not restart
Returns immediately.
@param reason: shutdown type: poweroff, reboot, suspend, halt
"""
dom = int(id)
+ id = str(id)
if dom <= 0:
return 0
if reason == 'halt':
self.domain_restart_cancel(id)
else:
- self.domain_restart_schedule(id, reason)
+ self.domain_restart_schedule(id, reason, set=1)
eserver.inject('xend.domain.shutdown', [id, reason])
if reason == 'halt':
reason = 'poweroff'
self.refresh_schedule()
return val
- def domain_restart_schedule(self, id, reason):
+ def domain_restart_schedule(self, id, reason, set=0):
"""Schedule a restart for a domain if it needs one.
@param id: domain id
@param reason: shutdown reason
"""
+ print 'domain_restart_schedule>', id, reason, set
dominfo = self.domain.get(id)
- if not dominfo or id in self.restarts:
- # Don't schedule if unknown or already there.
+ if not dominfo:
+ return
+ if id in self.restarts:
return
- restart = ((reason == 'reboot') or
- (reason == 'poweroff' and dominfo.autorestart))
+ if set and reason == 'reboot':
+ dominfo.restart_mode = XendDomainInfo.RESTART_ALWAYS
+ restart = dominfo.restart_needed(reason)
if restart:
- # Clear autorestart flag to avoid multiple restarts.
- dominfo.autorestart = 0
+ # Avoid multiple restarts.
+ dominfo.restart_mode = XendDomainInfo.RESTART_NEVER
self.restarts[id] = dominfo.config
print 'Scheduling restart for domain:', id, dominfo.name
self.domain_restarts_schedule()
"""
dominfo = self.domain.get(id)
if dominfo:
- dominfo.autorestart = 0
+ dominfo.restart_mode = XendDomainInfo.RESTART_NEVER
if id in self.restarts:
del self.restarts[id]
val = xc.domain_destroy(dom=dom)
return val
- def domain_destroy(self, id):
+ def domain_destroy(self, id, reason='halt'):
"""Terminate domain immediately.
- Cancels any restart for the domain.
+ - halt: cancel any restart for the domain
+ - reboot schedule a restart for the domain
@param id: domain id
"""
- self.domain_restart_cancel(id)
+ id = str(id)
+ if reason == 'halt':
+ self.domain_restart_cancel(id)
+ elif reason == 'reboot':
+ self.domain_restart_schedule(id, reason, set=1)
val = self.final_domain_destroy(id)
self.refresh_schedule()
return val
DOMAIN_REBOOT : "reboot",
DOMAIN_SUSPEND : "suspend" }
+RESTART_ALWAYS = 'always'
+RESTART_ONREBOOT = 'onreboot'
+RESTART_NEVER = 'never'
+
+restart_modes = [
+ RESTART_ALWAYS,
+ RESTART_ONREBOOT,
+ RESTART_NEVER,
+ ]
+
def shutdown_reason(code):
"""Get a shutdown reason from a code.
def make_disk(dom, uname, dev, mode, recreate=0):
"""Create a virtual disk device for a domain.
- @returns Deferred
+ @param dom: domain id
+ @param uname: device to export
+ @param dev: device name in domain
+ @param mode: read/write mode
+ @param recreate: recreate flag (after xend restart)
+ @return: deferred
"""
segments = lookup_disk_uname(uname)
if not segments:
returns Deferred
raises VmError for invalid configuration
"""
- print 'vm_create>'
vm = XendDomainInfo()
return vm.construct(config)
def _vm_configure1(val, vm):
d = vm.create_devices()
- #print '_vm_configure1> made devices...'
def cbok(x):
- #print '_vm_configure1> cbok', x
return x
d.addCallback(cbok)
d.addCallback(_vm_configure2, vm)
- #print '_vm_configure1<'
return d
def _vm_configure2(val, vm):
- #print '>callback _vm_configure2...'
d = vm.configure_fields()
def cbok(results):
- #print '_vm_configure2> cbok', results
return vm
def cberr(err):
- #print '_vm_configure2> cberr', err
vm.destroy()
return err
d.addCallback(cbok)
d.addErrback(cberr)
- #print '<_vm_configure2'
return d
class XendDomainInfo:
#todo: set to migrate info if migrating
self.migrate = None
#Whether to auto-restart
- self.autorestart = 0
+ self.restart_mode = RESTART_ONREBOOT
def setdom(self, dom):
self.dom = int(dom)
state = run + block + stop + susp + crash
sxpr.append(['state', state])
if self.info['shutdown']:
- reasons = ["poweroff", "reboot", "suspend"]
- reason = reasons[self.info['shutdown_reason']]
+ reason = shutdown_reason(self.info['shutdown_reason'])
sxpr.append(['shutdown_reason', reason])
sxpr.append(['cpu', self.info['cpu']])
sxpr.append(['cpu_time', self.info['cpu_time']/1e9])
try:
self.name = sxp.child_value(config, 'name')
self.memory = int(sxp.child_value(config, 'memory', '128'))
- if sxp.child(config, 'autorestart', None):
- self.autorestart = 1
+ self.configure_restart()
self.configure_backends()
image = sxp.child_value(config, 'image')
if image is None:
image_handler(self, image)
deferred = self.configure()
def cbok(x):
- print 'vm_create> cbok', x
return x
def cberr(err):
self.destroy()
# Catch errors, cleanup and re-raise.
self.destroy()
raise
- print 'vm_create<'
return deferred
def config_devices(self, name):
def cleanup(self):
"""Cleanup vm resources: release devices.
"""
- print 'cleanup>', self.dom
self.state = self.STATE_TERMINATED
self.release_devices()
def release_devices(self):
"""Release all vm devices.
"""
- print 'release_devices>', self.dom
self.release_vifs()
self.release_vbds()
self.devices = {}
def release_vifs(self):
"""Release vm virtual network devices (vifs).
"""
- print 'release_vifs>', self.dom
if self.dom is None: return
ctrl = xend.netif_get(self.dom)
if ctrl:
def release_vbds(self):
"""Release vm virtual block devices (vbds).
"""
- print 'release_vbds>', self.dom
if self.dom is None: return
ctrl = xend.blkif_get(self.dom)
if ctrl:
memory = self.memory
name = self.name
cpu = int(sxp.child_value(self.config, 'cpu', '-1'))
- print 'init_domain>', memory, name, cpu
+ #print 'init_domain>', memory, name, cpu
dom = xc.domain_create(mem_kb= memory * 1024, name= name, cpu= cpu)
if dom <= 0:
raise VmError('Creating domain failed: name=%s memory=%d'
print 'Warning: kernel cmdline too long'
dom = self.dom
buildfn = getattr(xc, '%s_build' % ostype)
- print 'build_domain>', ostype, dom, kernel, cmdline, ramdisk
+ #print 'build_domain>', ostype, dom, kernel, cmdline, ramdisk
flags = 0
if self.netif_backend: flags |= SIF_NET_BE_DOMAIN
if self.blkif_backend: flags |= SIF_BLK_BE_DOMAIN
cmdline kernel commandline
vifs_n number of network interfaces
"""
- print 'create_domain>', ostype, kernel
if not self.recreate:
if not os.path.isfile(kernel):
raise VmError('Kernel image does not exist: %s' % kernel)
if ramdisk and not os.path.isfile(ramdisk):
raise VmError('Kernel ramdisk does not exist: %s' % ramdisk)
- print 'create-domain> init_domain...'
self.init_domain()
- print 'create_domain>', 'dom=', self.dom
self.console = xendConsole.console_create(self.dom)
self.build_domain(ostype, kernel, ramdisk, cmdline, vifs_n)
self.image = kernel
returns Deferred
raises VmError for invalid devices
"""
- print '>create_devices'
dlist = []
devices = sxp.children(self.config, 'device')
index = {}
append_deferred(dlist, v)
index[dev_name] = dev_index + 1
deferred = defer.DeferredList(dlist, fireOnOneErrback=1)
- print '<create_devices'
return deferred
def device_create(self, dev_config):
self.config.remove(['device', dev_config])
dev.destroy()
+ def configure_restart(self):
+ r = sxp.child_value(self.config, 'restart', RESTART_ONREBOOT)
+ if r not in restart_modes:
+ raise VmError('invalid restart mode: ' + str(r))
+ self.restart_mode = r;
+
+ def restart_needed(self, reason):
+ if self.restart_mode == RESTART_NEVER:
+ return 0
+ if self.restart_mode == RESTART_ALWAYS:
+ return 1
+ if self.restart_mode == RESTART_ONREBOOT:
+ return reason == 'reboot'
+ return 0
+
def configure_backends(self):
"""Set configuration flags if the vm is a backend for netif of blkif.
"""
args = sxp.child_value(image, "args")
if args:
cmdline += " " + args
- ramdisk = sxp.child_value(image, "ramdisk")
+ ramdisk = sxp.child_value(image, "ramdisk", '')
vifs = vm.config_devices("vif")
vm.create_domain("netbsd", kernel, ramdisk, cmdline, len(vifs))
return vm
dev = xend.netif_dev(vm.dom, vif)
dev.vifctl('up', vmname=vm.name)
vm.add_device('vif', dev)
- print 'vm_dev_vif> created', dev
return id
defer.addCallback(fn)
return defer
return val
def op_destroy(self, op, req):
- val = self.xd.domain_destroy(self.dom.id)
+ fn = FormFn(self.xd.domain_destroy,
+ [['dom', 'int'],
+ ['reason', 'str']])
+ val = fn(req.args, {'dom': self.dom.id})
req.setHeader("Location", "%s/.." % req.prePathURL())
return val
req.write('<form method="post" action="%s">' % url)
req.write('<input type="submit" name="op" value="unpause">')
req.write('<input type="submit" name="op" value="pause">')
+ req.write('</form>')
+
+ req.write('<form method="post" action="%s">' % url)
req.write('<input type="submit" name="op" value="destroy">')
+ req.write('<input type="radio" name="reason" value="halt" checked>Halt')
+ req.write('<input type="radio" name="reason" value="reboot">Reboot')
req.write('</form>')
req.write('<form method="post" action="%s">' % url)
fn=set_value, default=128,
use="Domain memory in MB.")
-gopts.var('autorestart', val='no|yes',
- fn=set_bool, default=0,
- use="Whether to restart the domain on exit.")
+gopts.var('restart', val='onreboot|always|never',
+ fn=set_value, default=None,
+ use="""Whether the domain should be restarted on exit.
+ - onreboot: restart on exit with shutdown code reboot
+ - always: always restart on exit, ignore exit code
+ - never: never restart on exit, ignore exit code
+ """)
gopts.var('blkif', val='no|yes',
fn=set_bool, default=0,
config.append(['backend', ['blkif']])
if vals.netif:
config.append(['backend', ['netif']])
- if vals.autorestart:
- config.append(['autorestart'])
+ if vals.restart:
+ config.append(['restart', vals.restart])
configure_image(config, vals)
config_devs = []
--- /dev/null
+# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
+
+"""Destroy a domain.
+"""
+
+from xen.xend.XendClient import server
+from xen.xm.opts import *
+
+gopts = Opts(use="""[options] [DOM]
+
+Destroy a domain, optionally restarting it.
+""")
+
+gopts.opt('help', short='h',
+ fn=set_true, default=0,
+ use="Print this help.")
+
+gopts.opt('reboot', short='R',
+ fn=set_true, default=0,
+ use='Destroy and restart.')
+
+def main(argv):
+ opts = gopts
+ args = opts.parse(argv)
+ if opts.vals.help:
+ opts.usage()
+ return
+ if len(args) < 1: opts.err('Missing domain')
+ dom = args[0]
+ try:
+ domid = int(dom)
+ except:
+ opts.err('Invalid domain: ' + dom)
+ if opts.vals.reboot:
+ mode = 'reboot'
+ else:
+ mode = 'halt'
+ server.xend_domain_destroy(domid, mode)
+
+
from xen.xend import sxp
from xen.xend.XendClient import XendError, server
from xen.xend.XendClient import main as xend_client_main
-from xen.xm import create, shutdown
+from xen.xm import create, destroy, shutdown
class Prog:
"""Base class for sub-programs.
info = """Terminate a domain immediately."""
def help(self, args):
- print args[0], 'DOM'
- print '\nTerminate domain DOM immediately.'
+ destroy.main([args[0], '-h'])
def main(self, args):
- if len(args) < 2: self.err("%s: Missing domain" % args[0])
- dom = args[1]
- server.xend_domain_destroy(dom)
+ destroy.main(args)
xm.prog(ProgDestroy)